iT邦幫忙

2024 iThome 鐵人賽

DAY 10
1
AI/ ML & Data

深度學習的學習之旅:從理論到實作系列 第 10

[Day10] Q-Learning 深入解讀:FrozenLakeAgent 訓練流程全解析

  • 分享至 

  • xImage
  •  

前言

昨天介紹了有關gymnasium的一些基礎概念,而今天我們會一步一步來建立我們的Frozen Lake。這篇文章寫得有點亂,自己一時之間也沒有想到更好的改法,請大家見諒。

實作開始

首先我將這整個定義成一個類別FrozenLakeAgent,並初始化一些參數,在未來會使用到,而其中一些參數在第8天的時候有提到過,如果有人忘記了,可以回去複習一下喔。

我們的類別內主要會有以下幾個功能:

  1. train
  2. plot_rewards
  3. save_q_table
  4. load_q_table
  5. run
  6. evaluate

參數初始化

def __init__(self, map_name="8x8", is_slippery=True, alpha=0.9, gamma=0.9, epsilon=1, epsilon_decay_rate=0.0001):
    self.map_name = map_name
    self.is_slippery = is_slippery
    self.alpha = alpha
    self.gamma = gamma
    self.epsilon = epsilon
    self.epsilon_decay_rate = epsilon_decay_rate
    self.rng = np.random.default_rng()
  1. is_slippery (預設值: True)
    • 功能: 決定環境是否滑溜(滑動機率)。
    • 如果設為 True,代理在移動時會有滑動的可能,這會讓環境更有挑戰性,因為我們的代理可能無法按照預期行動。如果設為 False,則每次移動都會完全按照指定的方向進行,降低環境的複雜性。
  2. epsilon (預設值: 1)
    • 功能: 探索率(Exploration Rate)。
    • epsilon 控制代理在選擇行為時隨機性(探索)與基於 Q 表的策略(利用)的平衡。epsilon 的值越高,代理越傾向於隨機選擇行為來探索環境;epsilon 的值越低,代理則越傾向於選擇 Q 表中獲得的最佳行為。1 表示完全隨機探索,初期設置為 1 可以確保代理能夠充分探索環境。
  3. epsilon_decay_rate (預設值: 0.0001)
    • 功能: 探索率的衰減速率。
    • 隨著訓練進行,epsilon 會逐漸減少,這樣代理會從初期的全面探索逐漸過渡到更多的利用學到的知識。epsilon_decay_rate 控制衰減的速度。0.0001 是一個相對較小的值,確保探索率緩慢下降,從而使得代理在訓練後期能夠更穩定地利用已學到的知識。
  4. rng (預設值: np.random.default_rng())
    • 功能: 隨機數生成器。
    • 使用 numpy 的隨機數生成器來生成隨機數,這對於行為選擇和其他隨機操作至關重要。這裡使用 default_rng() 方法來創建一個新的隨機數生成器對象,以提供更好的隨機性和控制。

這裡面有很多參數在Day8介紹Q-Learning的時候有提到,如果有忘記的部分,可以回去看看文章。

訓練

接著來到我們主要的訓練部分,在這裡我們定義了一個 train 函數,這個函數的主要功能是讓代理在多次遊玩 Frozen Lake 的過程中,不斷更新 Q table,從中學習如何獲得最大的回報。

def train(self, episodes, render=False):
    if render:
        self.env = gym.make('FrozenLake-v1', map_name=self.map_name, is_slippery=self.is_slippery, render_mode='human')
    else:
        self.env = gym.make('FrozenLake-v1', map_name=self.map_name, is_slippery=self.is_slippery)
    self.q_table = np.zeros((self.env.observation_space.n, self.env.action_space.n))
    # 創建一個零值的 Q-table,大小為 (狀態數, 行動數)。Q-table 用於儲存每個狀態下的每個行動的 Q 值(即價值),並在訓練過程中進行更新。每個格子對應於一個狀態-行動組合的預期獎勵。
    # self.env.observation_space.n:表示環境中所有可能狀態的數量。
    # self.env.action_space.n:表示環境中可用的行動數量(如上、下、左、右四個方向)。
self.env.observation_space.n:表示環境中所有可能狀態的數量。
self.env.action_space.n:表示環境中可用的行動數量(如上、下、左、右四個方向)。
    rewards_per_episode = np.zeros(episodes)

在 train 函數中,我們首先初始化 Q 表格,其大小是根據環境的狀態空間與行動空間決定的,然後開始進行多次遊玩,這裡我們會傳入 episodes 參數來決定遊玩的次數。

  • 如果 render=True,則環境會以人類可讀的視覺模式運行(即展示 Frozen Lake 版圖和代理的移動)。 render=False,則環境只會進行模擬,而不會有畫面顯示。(昨天有提到更詳細的介紹喔)

接著在每次遊戲中,代理需要根據 epsilon-greedy 策略選擇行動,並不斷更新 Q 表格以學習環境。
而什麼是epsilon-greedy策略呢?我們留在明天繼續介紹!今天先把程式碼的部分介紹完。(文章的結構編排真的好難,想了很久還是沒想到要怎麼介紹比較好)

for i in range(episodes):
    state = self.env.reset()[0]
    terminated = False
    truncated = False

    while not terminated and not truncated:
        if self.rng.random() < self.epsilon:
            action = self.env.action_space.sample()  # 探索
        else:
            action = np.argmax(self.q_table[state, :])  # 利用
        new_state, reward, terminated, truncated, _ = self.env.step(action)
        self.q_table[state, action] += self.alpha * (reward + self.gamma * np.max(self.q_table[new_state, :]) - self.q_table[state, action])
        state = new_state

  1. terminated = Falsetruncated = False

    • 這兩個變數用來控制每回合的結束條件:
      • terminated 表示遊戲是否結束(如達到終點)。
      • truncated 表示是否因為其他限制(如步數限制)而中斷遊戲。當這兩個變數為 False 時,代理會繼續進行決策。
    • 所以在這些條件沒有達成前,他將會不斷進行決策並和環境互動。
  2. if self.rng.random() < self.epsilon:

    • 這裡運用了 Epsilon-Greedy 策略 來決定代理是進行探索(exploration)還是利用(exploitation):

      • self.rng.random() 會生成一個 0 到 1 之間的隨機數。
      • self.epsilon 是當前的探索率,如果隨機數小於 epsilon,代理將進行探索。
    • 探索:action = self.env.action_space.sample()

      • 如果隨機數小於 epsilon,代理會選擇隨機行動,這被稱為 探索。隨機行動可以幫助代理發現新的策略,避免陷入局部最優解。
    • 利用:action = np.argmax(self.q_table[state, :])

      • 如果隨機數大於等於 epsilon,代理將選擇當前狀態下 Q 表中對應的最優行動,即 利用 代理從過去的經驗中學到的知識來進行行動。
  3. new_state, reward, terminated, truncated, _ = self.env.step(action)

    • 這行程式碼是代理根據選擇的行動與環境互動的步驟:
      • self.env.step(action) 執行選定的行動,並返回以下五個值:
      • new_state: 行動後的下一個狀態。
      • reward: 代理在執行該行動後獲得的即時獎勵(通常是 0 或 1)。
      • terminated: 表示回合是否已經結束。
      • truncated: 表示是否因其他因素(如步數限制)而中止回合。
      • _: 這是額外的資訊,在這裡不需要使用。
    • 之後將這些資訊用來更新 Q-table:
  4. 最後state = new_state

    • 將 state 更新為 new_state,準備進行下一次迭代,直到回合結束(terminated 或 truncated 變為 True)。

結語

今天先將初始化及訓練的部分先完成及介紹,我們可以注意到整個Q-learning的核心訓練流程,並且介紹了如何透過Epsilon greedy strategy策略來平衡探索與利用。這是強化學習中的重要概念,能夠幫助代理逐步學會如何在環境中做出最佳決策。今天的篇幅有點長,所以明天會接續將未完成的部分繼續完成。


上一篇
[Day9] 當強化學習遇上健身房!?
下一篇
[Day 11] 從理論到實踐:完成Frozen Lake的Q-learning訓練
系列文
深度學習的學習之旅:從理論到實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言